<template>
    <!-- 表发新闻 -->
    <div class="setNews">
        <setNewsTop :funs="fns">
            <template #title>
                <el-input v-model="title" style="width: 70%;" placeholder="请输入标题" />
                <el-select v-model="selectValue" class="m-2" multiple collapse-tags collapse-tags-tooltip
                    placeholder="Select" style="margin-left: 5px; margin-right: 5px; width: 250px;">
                    <el-option v-for="item in options" :key="item.id" :label="item.type" :value="item.id" />
                </el-select>
            </template>
        </setNewsTop>
        <div class="ws" style="border: 1px solid #ccc ;flex: 1; ;" v-loading="loading">
            <Toolbar style="border-bottom: 1px solid #ccc; " :editor="editorRef" :defaultConfig="toolbarConfig" />
            <Editor style="position: relative; flex: 1; width: 100%; " v-model="valueHtml" :defaultConfig="editorConfig"
                @onCreated="handleCreated" />
        </div>
        <el-button @click="sends" style="margin-top: 20px; padding: 2.5vh 0px;" type="primary">发表文章</el-button>
</div>
</template>
<script lang="ts" setup>


import { ref, shallowRef, onBeforeUnmount, toRefs, reactive } from "vue"
import setNewsTop from "./setNewsTop.vue"
import { picturePreview, sendMessage, optionsList } from '@/request/api'
import '@wangeditor/editor/dist/css/style.css' // 引入 css
import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import type { SlateElement } from '@wangeditor/editor'
import type { opliset } from '@/type/news'
import { ElMessage } from 'element-plus'
import { useRouter } from "vue-router"
import { useWebSocket, routerHis, activ } from '@/hooks/index'
// import { DomEditor } from '@wangeditor/editor'
const router=useRouter()
let loading = ref(false)

type VideoElement = SlateElement & {
    src: string
    poster?: string
}
type ImageElement = SlateElement & {
    src: string
    alt: string
    url: string
    href: string
}
// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef()
// 内容 HTML
const valueHtml = ref('')
//菜单配置
const toolbarConfig: any = {}
//排除掉某些菜单
toolbarConfig.excludeKeys = [
    'headerSelect',     //去掉标题功能
    "fullScreen"            //去除全屏功能
]
const editorConfig: any = { placeholder: '请输入内容...', MENU_CONF: {} }
// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
    const editor = editorRef.value
    if (editor == null) return
    editor.destroy()
})
const handleCreated = (editor: any) => {
    editorRef.value = editor // 记录 editor 实例，重要！
    //     setTimeout(()=>{
    //         const toolbar = DomEditor.getToolbar(editor)

    // const curToolbarConfig = toolbar.getConfig()
    // console.log( curToolbarConfig.toolbarKeys ) // 当前菜单排序和分组
    //     },500)
}
//插入图片
function customCheckImageFn(src: string, alt: string, url: string): boolean | undefined | string { // TS 语法
    // function customCheckImageFn(src, alt, url) {                                                    // JS 语法

    if (!src) {
        return
    }
    if (src.indexOf('http') !== 0) {
        return '图片网址必须以 http/https 开头'
    }
    return true

    // 返回值有三种选择：
    // 1. 返回 true ，说明检查通过，编辑器将正常插入图片
    // 2. 返回一个字符串，说明检查未通过，编辑器会阻止插入。会 alert 出错误信息（即返回的字符串）
    // 3. 返回 undefined（即没有任何返回），说明检查未通过，编辑器会阻止插入。但不会提示任何信息
}

editorConfig.MENU_CONF['insertImage'] = {
    onInsertedImage(imageNode: ImageElement | null) {  // TS 语法
        // onInsertedImage(imageNode) {                    // JS 语法

        if (imageNode == null) return

        const { src, alt, url, href } = imageNode
    },
    checkImage: customCheckImageFn, // 也支持 async 函数
    // parseImageSrc: customParseImageSrc, // 也支持 async 函数
}

//引入图片触发
editorConfig.MENU_CONF['uploadImage'] = {
    // 自定义上传
    async customUpload(file: File, insertFn: any) {  // TS 语法
        // async customUpload(file, insertFn) {                   // JS 语法
        // file 即选中的文件
        // 自己实现上传，并得到图片 url alt href
        // 最后插入图片
        if (file.type == 'image/jpeg') {
            loading.value = true
            picturePreview<{ image: File }>({
                image: file
            }).then(res => {
                urls.push(res.data[0])
                insertFn(res.data[0], file.name, file.type)
                loading.value = false
            })
        } else {
            ElMessage({
                showClose: true,
                message: '请上传image/jpeg文件',
                type: 'error',
            })
        }
    }
}

//收集图片地址
const urls: string[] = []
//收集视频地址
const videoUrl: string[] = []
// 编辑图片
// editorConfig.MENU_CONF['editImage'] = {
//     onUpdatedImage(imageNode: ImageElement | null) {  // TS 语法
//         // onUpdatedImage(imageNode) {                    // JS 语法
//         if (imageNode == null) return

//         const { src, alt, url } = imageNode
//         console.log('updated image', src, alt, url)
//     },
//     checkImage: customCheckImageFn, // 也支持 async 函数
//     // parseImageSrc: customParseImageSrc, // 也支持 async 函数
// }


// 自定义校验视频
function customCheckVideoFn(src: string, poster: string): boolean | string | undefined {  // TS 语法
    // function customCheckVideoFn(src, poster) {                                             // JS 语法
    return true

    // 返回值有三种选择：
    // 1. 返回 true ，说明检查通过，编辑器将正常插入视频
    // 2. 返回一个字符串，说明检查未通过，编辑器会阻止插入。会 alert 出错误信息（即返回的字符串）
    // 3. 返回 undefined（即没有任何返回），说明检查未通过，编辑器会阻止插入。但不会提示任何信息
}

// 自定义转换视频
function customParseVideoSrc(src: string): string {  // TS 语法
    // function customParseVideoSrc(src) {               // JS 语法
    if (src.includes('.bilibili.com')) {
        // 转换 bilibili url 为 iframe （仅作为示例，不保证代码正确和完整）
        const arr = location.pathname.split('/')
        const vid = arr[arr.length - 1]
        return `<iframe src="//player.bilibili.com/player.html?bvid=${vid}" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true"> </iframe>`
    }
    return src
}

editorConfig.MENU_CONF['insertVideo'] = {
    onInsertedVideo(videoNode: VideoElement | null) {  // TS 语法
        // onInsertedVideo(videoNode) {                    // JS 语法
        if (videoNode == null) return

        const { src } = videoNode
    },
    checkVideo: customCheckVideoFn, // 也支持 async 函数
    parseVideoSrc: customParseVideoSrc, // 也支持 async 函数
}
editorConfig.MENU_CONF['uploadVideo'] = {
    // 自定义上传
    async customUpload(file: File, insertFn: any) {  // TS 语法
        // async customUpload(file, insertFn) {                   // JS 语法
        // file 即选中的文件
        // 自己实现上传，并得到视频 url poster
        // 最后插入视频

        if (file.type == 'video/mp4') {
            loading.value = true
            picturePreview<{ image: File }>({
                image: file
            }).then(res => {
                videoUrl.push(res.data[0])
                insertFn(res.data[0], file.name)
                loading.value = false
            })
        } else {
            ElMessage({
                showClose: true,
                message: '请上传video/mp4文件',
                type: 'error',
            })
        }

        // insertFn(url, poster)
    }
}

//过滤现在还存在的地址
const urlFilter = (name: string): string[] => {
    let arr: any = editorRef.value.getElemsByType(name)
    let url: string[] = []
    arr.filter((element: any) => {
        return name == 'image' ? urls.includes(element.src) : videoUrl.includes(element.src)
    }).forEach((e: any) => {
        url.push(e.src)
    })
    return url
}
const fns = (multipleSelection: any) => {
    userIds.length=0
    userIds.push(...multipleSelection.reduce((pre: string[], value: any) => {
        pre.push(value.id)
        return pre
    }, []))
    
}
const title = ref('')     //标题
const userIds:number[] = []            //不让看的人
let selectValue = ref<number[]>([])       //分类详情
const options = reactive<opliset[]>([])      //分类集合
//开始获取分类信息
optionsList().then(res => {
    options.length = 0
    selectValue.value.length = 0
    options.push(...res.data)
    selectValue.value.push(res.data[0].id)
})
//发送文章
const sends = () => {
    //获取当前富文本里面的图片

    // console.log(editorRef.value.getElemsByType('image'));
    // let file = new window.File([arr[0].src],arr[0].alt,{type:'image/jpeg'})
    // console.log(editorRef.value.getHtml());
   
    if (!include('查看新闻')) {
        routerHis.value.push({
            value:"查看新闻",
            path: '/home/' + 'news/shownews',
            parent: '新闻专栏',
            index:'3-1'
        })
        activ.value++
    }



    sendMessage({
        userIds: [...userIds],
        kinds: selectValue.value,
        title: title.value,
        content: editorRef.value.getHtml(),
        urlList: [...urlFilter('image'), ...urlFilter('video')],
    }).then(res => {
        valueHtml.value = ''
        title.value=''
        return res.data ? Promise.resolve(res.data) : Promise.reject(res.msg)
    }).then((res: string) => {
        ElMessage({
            message: res,
            type: 'success',
        })
        router.push({
            path:'/home/news/shownews',
            query:{
                set:1
            }
        })
    }).catch(err => {
        ElMessage.error(err)
    })
}
const include = (value: string) => {
    let mark = false
    for (let i = 0; i < routerHis.value.length; i++) {
        if (routerHis.value[i].value == value) {
            activ.value = i
            mark = true
            break
        }
    }
    return mark ? 1 : 0
}
</script>

<style lang=less  scoped>
:deep(.w-e-textarea-video-container) {
    text-align: left !important;
}

.setNews {
    display: flex;
    flex-direction: column;
}

.ws {
    .setNews();
    position: relative;
}
:deep(.w-e-text-container){
    // height: 100%;
    width: 100%;
    overflow: hidden;
    position: absolute;
    // overflow: scroll;
}
:deep(.w-e-scroll){
    overflow-y: scroll !important;
}
:deep(.w-e-textarea-1){
    box-sizing: border-box;
}
</style>